home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (c) Silicon Graphics, 1996. */
-
- /* This program is freely distributable without licensing fees
- and is provided without guarantee or warrantee expressed or
- implied. This program is -not- in the public domain. */
-
- /* CC -o glrduckpond glrduckpond.c++ -lGLR -lglut -lInventor -lGL -lGLU -lXmu -lXext -lX11 -lm */
-
- #include <stdio.h>
- #include <unistd.h>
-
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glr.h>
- #include <GL/glut.h>
-
- #include <Inventor/SoDB.h>
- #include <Inventor/SoInput.h>
- #include <Inventor/SbViewportRegion.h>
- #include <Inventor/nodes/SoSeparator.h>
- #include <Inventor/actions/SoGLRenderAction.h>
- #include <Inventor/nodes/SoCylinder.h>
- #include <Inventor/nodes/SoDirectionalLight.h>
- #include <Inventor/nodes/SoEventCallback.h>
- #include <Inventor/nodes/SoMaterial.h>
- #include <Inventor/nodes/SoPerspectiveCamera.h>
- #include <Inventor/nodes/SoRotationXYZ.h>
- #include <Inventor/nodes/SoTransform.h>
- #include <Inventor/nodes/SoTranslation.h>
- #include <Inventor/engines/SoElapsedTime.h>
- #include <Inventor/engines/SoGate.h>
- #include <Inventor/nodes/SoComplexity.h>
-
- int first = 1;
- int quality = 1;
- int W = 300, H = 300;
- int timeout = 5000, waitTime = 250;
- int spinning = 0;
- int win;
- GLrSession session;
- GLrCanvasType canvasType;
- GLrCanvas canvas;
- GLubyte *image = NULL;
- int sceneChanged = 1;
- SoSeparator *localDuck, *remoteDuck, *root;
- SoRotationXYZ *duckRotXYZ, *localRot, *remoteRot;
- float angle = 0.0;
-
- void
- reshape(int w, int h)
- {
- float areaChange;
-
- areaChange = ((float) w*h)/((float) W*H) + 0.20; /* areaChange has 20% increase slop */
- timeout = (int)((float) timeout * areaChange);
- sceneChanged = 1;
- glViewport(0, 0, w, h);
- W = w;
- H = h;
- if (image)
- free(image);
- image = (GLubyte *) malloc(W * H * 3);
- }
-
- void
- renderScene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- SbViewportRegion myViewport(W, H);
- SoGLRenderAction myRenderAction(myViewport);
- myRenderAction.apply(root);
- }
-
- void
- prepImageBlit(void)
- {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluOrtho2D(0, W, 0, H);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glDisable(GL_DEPTH_TEST);
- }
-
- void
- postImageBlit(void)
- {
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glEnable(GL_DEPTH_TEST);
- }
-
- void
- output(int x, int y, char *string)
- {
- int len, i;
-
- glRasterPos2i(x, y);
- len = (int) strlen(string);
- for (i = 0; i < len; i++) {
- glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
- }
- }
-
- void
- redraw(void)
- {
- int status, attempt, expired;
- char message[40];
-
- if(quality && !first) {
- prepImageBlit();
- if(sceneChanged) {
- attempt = 0;
- expired = 0;
- glDrawBuffer(GL_FRONT);
- glDisable(GL_LIGHTING);
- do {
- if(waitTime > 10) {
- attempt++;
- if(expired > 0) {
- glColor3f(1.0, 0.0, 0.0);
- } else {
- glColor3f(1.0, 1.0, 1.0);
- }
- sprintf(message, "Interval: %-8d", timeout);
- output(10, H - 10 - 10*attempt, message);
- attempt++;
- }
-
- status = glrBeginRenderInterval(canvas, W, H, timeout, waitTime);
- if(status == 0) {
- waitTime = 10;
- glutSetWindow(win);
- glDrawBuffer(GL_BACK);
- postImageBlit();
- goto localRender;
- }
- waitTime = 250;
- root = remoteDuck;
- renderScene();
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
- status = glrEndRenderInterval(canvas, &timeout);
-
- if(status == 0) {
- glutSetWindow(win);
- expired++;
- }
- timeout = (int)((float) timeout * 1.4);
- } while(!status);
- sceneChanged = 0;
- }
-
- /* XXX Careful! Versions of GLUT through 2.2.1 tried to cache the
- current window/context binding to avoid unnecessary glXMakeCurrent
- calls, but using GLR and GLUT together violates the assumption
- that only GLUT called glXMakeCurrent. */
- glutSetWindow(win);
- glDrawBuffer(GL_BACK);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glRasterPos2i(0, 0);
- glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
- postImageBlit();
- glFinish();
- glutSwapBuffers();
- } else {
- localRender:
- root = localDuck;
- renderScene();
- glFinish();
- glutSwapBuffers();
- if(first) {
- first = 0;
- glutPostRedisplay();
- }
- }
- }
-
- int ms_attrs[] =
- {GLR_RGBA, GLR_RED_SIZE, 1, GLR_GREEN_SIZE, 1, GLR_BLUE_SIZE, 1, GLR_DEPTH_SIZE, 16, GLR_SAMPLES_SGIS, 4, 0};
- int attrs[] =
- {GLR_RGBA, GLR_RED_SIZE, 1, GLR_GREEN_SIZE, 1, GLR_BLUE_SIZE, 1, GLR_DEPTH_SIZE, 16, 0};
-
- SoSeparator*
- duckScene(float complex)
- {
- root = new SoSeparator;
- root->ref();
-
- SoComplexity *complexity = new SoComplexity;
- complexity->value = complex;
- root->addChild(complexity);
-
- // Add a camera and light
- SoPerspectiveCamera *myCamera = new SoPerspectiveCamera;
- myCamera->position.setValue(0., -4., 8.0);
- myCamera->heightAngle = M_PI/2.5;
- myCamera->nearDistance = 1.0;
- myCamera->farDistance = 15.0;
- root->addChild(myCamera);
- root->addChild(new SoDirectionalLight);
-
- // Rotate scene slightly to get better view
- SoRotationXYZ *globalRotXYZ = new SoRotationXYZ;
- globalRotXYZ->axis = SoRotationXYZ::X;
- globalRotXYZ->angle = M_PI/9;
- root->addChild(globalRotXYZ);
-
- // Pond group
- SoSeparator *pond = new SoSeparator;
- root->addChild(pond);
- SoMaterial *cylMaterial = new SoMaterial;
- cylMaterial->diffuseColor.setValue(0., 0.3, 0.8);
- pond->addChild(cylMaterial);
- SoTranslation *cylTranslation = new SoTranslation;
- cylTranslation->translation.setValue(0., -6.725, 0.);
- pond->addChild(cylTranslation);
- SoCylinder *myCylinder = new SoCylinder;
- myCylinder->radius.setValue(4.0);
- myCylinder->height.setValue(0.5);
- pond->addChild(myCylinder);
-
- // Duck group
- SoSeparator *duck = new SoSeparator;
- root->addChild(duck);
-
- // Read the duck object from a file and add to the group
- SoInput myInput;
- if (!myInput.openFile("duck.iv")) {
- if (!myInput.openFile("/usr/share/src/Inventor/examples/data/duck.iv")) {
- return NULL;
- }
- }
- SoSeparator *duckObject = SoDB::readAll(&myInput);
- if (duckObject == NULL) return NULL;
-
- // Set up the duck transformations
- duckRotXYZ = new SoRotationXYZ;
- duck->addChild(duckRotXYZ);
- duckRotXYZ->angle = angle;
- duckRotXYZ->axis = SoRotationXYZ::Y; // rotate about Y axis
- SoTransform *initialTransform = new SoTransform;
- initialTransform->translation.setValue(0., 0., 3.);
- initialTransform->scaleFactor.setValue(6., 6., 6.);
- duck->addChild(initialTransform);
-
- duck->addChild(duckObject);
-
- return root;
- }
-
- void
- updateModels(void)
- {
- sceneChanged = 1;
- localRot->angle = angle;
- remoteRot->angle = angle;
- glutPostRedisplay();
- }
-
- void
- animate(void)
- {
- angle += 0.1;
- updateModels();
- }
-
- void
- setAnimation(int enable)
- {
- if(enable) {
- quality = 0;
- spinning = 1;
- glutIdleFunc(animate);
- } else {
- sceneChanged = 1;
- quality = 1;
- spinning = 0;
- glutIdleFunc(NULL);
- sceneChanged = 1;
- glutPostRedisplay();
- }
- }
-
- /* ARGSUSED */
- void
- keyboard(unsigned char ch, int x, int y)
- {
- if(ch == ' ') {
- setAnimation(0);
- animate();
- }
- }
-
- void
- menuSelect(int item)
- {
- switch(item) {
- case 1:
- animate();
- break;
- case 2:
- if(!spinning) {
- setAnimation(1);
- } else {
- setAnimation(0);
- }
- break;
- }
- }
-
- void
- vis(int visible)
- {
- if (visible == GLUT_VISIBLE) {
- if (spinning)
- glutIdleFunc(animate);
- } else {
- if (spinning)
- glutIdleFunc(NULL);
- }
- }
-
- void
- gfxinit(void)
- {
- glEnable(GL_DEPTH_TEST);
- glClearColor(0.132, 0.542, 0.132, 1.0);
- }
-
- int moving = 0;
- int begin;
-
- /* ARGSUSED */
- void
- mouse(int button, int state, int x, int y)
- {
- if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
- setAnimation(0);
- moving = 1;
- begin = x;
- quality = 0;
- }
- if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
- moving = 0;
- quality = 1;
- sceneChanged = 1;
- glutPostRedisplay();
- }
- }
-
- /* ARGSUSED */
- void
- motion(int x, int y)
- {
- if (moving) {
- angle = angle + .01 * (x - begin);
- begin = x;
- updateModels();
- }
- }
-
- void
- main(int argc, char **argv)
- {
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
-
- SoDB::init();
-
- localDuck = duckScene(0.4);
- if(localDuck == NULL) {
- fprintf(stderr, "couldn't read IV file\n");
- exit(1);
- }
- localRot = duckRotXYZ;
-
- remoteDuck = duckScene(0.9);
- if(remoteDuck == NULL) {
- fprintf(stderr, "couldn't read IV file\n");
- exit(1);
- }
- remoteRot = duckRotXYZ;
-
- session = glrOpenSession(NULL);
- if (session == NULL) {
- fprintf(stderr, "couldn't get GLR session\n");
- exit(1);
- }
- canvasType = glrGetCanvasType(session, ms_attrs);
- if (canvasType == NULL) {
- canvasType = glrGetCanvasType(session, attrs);
- if (canvasType == NULL) {
- fprintf(stderr, "couldn't get usable canvas type\n");
- exit(1);
- }
- }
- canvas = glrCreateCanvas(canvasType, NULL);
-
- glrEstablishRenderState(canvas);
- gfxinit();
-
- glutInitWindowSize(W, H);
- win = glutCreateWindow("GLUT Inventor Multisampling");
- glutDisplayFunc(redraw);
- glutReshapeFunc(reshape);
- glutCreateMenu(menuSelect);
- glutAddMenuEntry("Step", 1);
- glutAddMenuEntry("Toggle animation", 2);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- glutKeyboardFunc(keyboard);
- glutMouseFunc(mouse);
- glutMotionFunc(motion);
- glutVisibilityFunc(vis);
- gfxinit();
-
- glutMainLoop();
- }
-